﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections.Specialized;
using System.Xml.Linq;
using System.Xml;
using System.IO;
using Word = Microsoft.Office.Interop.Word;
//using Novacode;

namespace TrueCloud.SF.DocoTool
{
    public partial class SFDocoTool : Form
    {
        public SFDocoTool()
        {
            InitializeComponent();
        }

        private void btnLogon_Click(object sender, EventArgs e)
        {
            Connection cn = new Connection("david@truecloud.com.au.fm", "70FC@@dm", "uh7eF1MngLDBtjKdgI5a6Hs1");
            //Connection cn = new Connection("test@theconquests.com", "70FCAAdm", "fA5RnvU1ERNhEBX4j55WVRZ8");
            bool result = cn.ConnectTo(WebService.Metadata);
            Metadata md = new Metadata();
                       
            StringCollection strb = md.getMetadataParentDescription();
            foreach (string parent in strb)
            {
                checkedListBox1.Items.Add(parent);
            }

            checkedListBox1.Sorted = true;

        }

        private void button2_Click(object sender, EventArgs e)
        {
            Metadata md = new Metadata();
            
            //String[] reportFiles = md.retrieveComponentsInFolders();
            String[] reportFiles = new String[]{"*"};
            md.retrieveComponents(reportFiles,this.textBox1);

           

        }

        private void button1_Click(object sender, EventArgs e)
        {

            var doc = XDocument.Load("Opportunity.xml");

            XNamespace ns = "http://soap.sforce.com/2006/04/metadata";
            var wf = doc.Elements(ns + "Workflow");

            var rules = from rule in wf.Elements(ns + "rules")
                        let workflowTrigger = rule.Elements(ns + "workflowTimeTriggers")
                        let x = rule.Element(ns + "workflowTriggers") 
                        select new
                        {
                            Name = rule.Element(ns + "fullName").Value,
                            Description = 
                                        (string)rule.Element(ns + "description") ?? String.Empty ,
                            Trigger = rule.Element(ns + "triggerType").Value,
                            isActive = rule.Element(ns + "active").Value,

                            Criteria = rule.Elements(ns + "criteriaItems")
                                .Select(c => new
                                {
                                    Field = c.Element(ns + "field").Value,
                                    Operation = c.Element(ns + "operation").Value,
                                    Value = c.Element(ns + "value").Value
                                }),

                            Alerts = from action in rule.Elements(ns + "actions")
                                     let actionType = action.Element(ns + "type")
                                     where actionType != null && actionType.Value == "Alert"
                                     join alert in wf.Elements(ns + "alerts") on action.Element(ns + "name").Value equals alert.Element(ns + "fullName").Value
                                     select new
                                     {
                                         Name = alert.Element(ns + "fullName").Value,
                                         Description = alert.Element(ns + "description").Value,
                                     },
                            Tasks = from action in rule.Elements(ns + "actions")
                                    let actionType = action.Element(ns + "type")
                                    where actionType != null && actionType.Value == "Task"
                                    join alert in wf.Elements(ns + "tasks") on action.Element(ns + "name").Value equals alert.Element(ns + "fullName").Value
                                    select new
                                    {
                                        Name = alert.Element(ns + "fullName").Value,
                                        Description = alert.Element(ns + "description").Value,
                                    },
                            Updates = from action in rule.Elements(ns + "actions")
                                      let actionType = action.Element(ns + "type")
                                      where actionType != null && actionType.Value == "FieldUpdate"
                                      join alert in wf.Elements(ns + "fieldUpdates") on action.Element(ns + "name").Value equals alert.Element(ns + "fullName").Value
                                      select new
                                      {
                                          Name = alert.Element(ns + "fullName").Value,
                                          Description = alert.Element(ns + "literalValue").Value,
                                      },

                            TimeTriggerTasks = workflowTrigger != null ? from action in rule.Elements(ns + "workflowTimeTriggers").Elements(ns + "actions")
                                                                         let actionType = action.Element(ns + "type")
                                                                         where actionType != null && actionType.Value == "Task"
                                                                         join alert in wf.Elements(ns + "tasks") on action.Element(ns + "name").Value equals alert.Element(ns + "fullName").Value
                                                                         select new
                                                                         {
                                                                             Name = (string)alert.Element(ns + "fullName") ?? String.Empty,
                                                                             Description = (string)alert.Element(ns + "description") ?? String.Empty,
                                                                         } : null,
                            TimeTriggerUpdates = workflowTrigger != null ? from action in rule.Elements(ns + "workflowTimeTriggers").Elements(ns + "actions")
                                                                           let actionType = action.Element(ns + "type")
                                                                           where actionType != null && actionType.Value == "FieldUpdate"
                                                                           join alert in wf.Elements(ns + "fieldUpdates") on action.Element(ns + "name").Value equals alert.Element(ns + "fullName").Value
                                                                           select new
                                                                           {
                                                                               Name = (string)alert.Element(ns + "fullName") ?? String.Empty,
                                                                               Description = (string)alert.Element(ns + "literalValue") ?? String.Empty,
                                                                           } : null,


                            TimeTrigger = rule.Elements(ns + "workflowTimeTriggers")
                                .Select(c => new
                                {
                                    Length = c.Element(ns + "timeLength").Value,
                                    Unit = c.Element(ns + "workflowTimeTriggerUnit").Value
                                }),

                        };
           
            ///*
            // declare a new tree
            SimpleTree<LabelText> WorkFlow = new SimpleTree<LabelText>();

            // the tree will also be our root node
            SimpleTreeNode<LabelText> root = WorkFlow;

            root.Value = new LabelText("Workflow", "");

            foreach (var rule in rules)
            {
                SimpleTreeNode<LabelText> heading = root.Children.Add(new LabelText(rule.Name,""));
                SimpleTreeNode<LabelText> description = heading.Children.Add(new LabelText("Description", rule.Description));

                SimpleTreeNode<LabelText> triggerType = heading.Children.Add(new LabelText("Trigger Type",rule.Trigger));
                SimpleTreeNode<LabelText> isActive = heading.Children.Add(new LabelText("Active",rule.isActive));
                SimpleTreeNode<LabelText> criterion = heading.Children.Add(new LabelText("Criterion", "")); 
                
                foreach (var criteria in rule.Criteria)
                {
                    criterion.Children.Add(new LabelText("Criteria", criteria.Field + " " + criteria.Operation + " " + criteria.Value));
                }

                SimpleTreeNode<LabelText> alerts = heading.Children.Add(new LabelText("Alerts",""));
                foreach (var alert in rule.Alerts)
                {
                    alerts.Children.Add(new LabelText("Alert", alert.Name + " (" + alert.Description + ")"));
                }

                SimpleTreeNode<LabelText> tasks = heading.Children.Add(new LabelText("Tasks", ""));
                foreach (var alert in rule.Tasks)
                {
                    tasks.Children.Add(new LabelText("Task", alert.Name + " (" + alert.Description + ")"));
                }

                SimpleTreeNode<LabelText> updates = heading.Children.Add(new LabelText("Updates", ""));
                foreach (var alert in rule.Updates)
                {
                    updates.Children.Add(new LabelText("Update", alert.Name + " (" + alert.Description + ")"));
                }

                SimpleTreeNode<LabelText> workflowTimeTriggers = heading.Children.Add(new LabelText("Workflow Time Triggers", ""));
                SimpleTreeNode<LabelText> workflowTimeTriggersTasks = workflowTimeTriggers.Children.Add(new LabelText("Tasks", ""));
                foreach (var alert in rule.TimeTriggerTasks)
                {
                    workflowTimeTriggersTasks.Children.Add(new LabelText("Task", alert.Name + " (" + alert.Description + ")"));
                }

                SimpleTreeNode<LabelText> workflowTimeTriggersUpdates = workflowTimeTriggers.Children.Add(new LabelText("Updates", ""));
                foreach (var alert in rule.TimeTriggerUpdates)
                {
                    workflowTimeTriggersUpdates.Children.Add(new LabelText("Update", alert.Name + " (" + alert.Description + ")"));
                }

                foreach (var trigger in rule.TimeTrigger)
                {
                    SimpleTreeNode<LabelText> workflowTimeTriggerLength = workflowTimeTriggers.Children.Add(new LabelText("Trigger Length", trigger.Length));
                    SimpleTreeNode<LabelText> workflowTimeTriggerUnit = workflowTimeTriggers.Children.Add(new LabelText("Trigger Unit", trigger.Unit));
                }

                
            }

            Word.Application oWord = new Word.Application();
            object oMissing = System.Reflection.Missing.Value;
            Word.Document oDoc = oWord.Documents.Add(ref oMissing, ref oMissing, ref oMissing, ref oMissing);
            // display the whole subtree, passing in a SimpleTree
            OutputTreeToWord(WorkFlow, 0,oDoc);

            
            /*
            Word.Application oWord = new Word.Application();
            object oMissing = System.Reflection.Missing.Value;
            Word.Document oDoc = oWord.Documents.Add (ref oMissing, ref oMissing,ref oMissing, ref oMissing);
            Word.Table oTable;
            foreach (Workflow workflow in Workflows)
            {
                Word.Paragraph oPara1;
                oPara1 = oDoc.Paragraphs.Add(ref oMissing);

                object styleHeading1 = "Heading 1";
                oPara1.Range.set_Style(ref styleHeading1);
                oPara1.Range.Text = workflow.Name;
                oPara1.Range.InsertParagraphAfter();
                                            
                oTable = oDoc.Tables.Add(oPara1.Range,4,2,ref oMissing,ref oMissing);
                oTable.Borders.Enable = 1;    
                oTable.Range.ParagraphFormat.SpaceAfter = 6;
                oTable.Rows.Add();
                oTable.Cell(1,1).Range.Text = "Description";
                oTable.Cell(1,1).Range.Font.Bold = 1;
                oTable.Cell(2,1).Range.Text = "Trigger Type";
                oTable.Cell(2,1).Range.Font.Bold = 1;
                oTable.Cell(3,1).Range.Text = "Active";
                oTable.Cell(3,1).Range.Font.Bold = 1;
                oTable.Cell(4, 1).Range.Text = "Criteria";
                oTable.Cell(4, 1).Range.Font.Bold = 1;
                oTable.Cell(1, 2).Range.Text = workflow.Description;
                oTable.Cell(2, 2).Range.Text = workflow.TriggerType.ToString();
                oTable.Cell(3, 2).Range.Text = workflow.isActive.ToString();
                int i = 4;
                foreach (CriteriaItem ci in workflow.CriteriaItems)
                {
                    
                    oTable.Cell(i, 2).Range.Text = ci.Field.ToString() + " " + ci.Operation.ToString() + " " + ci.sValue.ToString();
                    //oTable.Rows.Add();
                    i++;
                }

                
                oPara1.Range.InsertParagraphAfter();
                
                
                
            }
*/
            object fileName = "C:\\SF\\Workflows.doc";
            oDoc.SaveAs(ref fileName,
            ref oMissing, ref oMissing,
            ref oMissing, ref oMissing,
            ref oMissing, ref oMissing,
            ref oMissing, ref oMissing,
            ref oMissing, ref oMissing);

            oDoc.Close (ref oMissing, ref oMissing, ref oMissing);
            oWord.Quit(ref oMissing, ref oMissing, ref oMissing);
            oWord = null; 
            
        }

        


        private void button3_Click(object sender, EventArgs e)
        {
            // declare a new tree
            SimpleTree<string> MakeDinnerTree = new SimpleTree<string>();

            // the tree will also be our root node
            SimpleTreeNode<string> root = MakeDinnerTree;
            root.Value = "make dinner";

            SimpleTreeNode<string> prepare = root.Children.Add("prepare ingredients");
            prepare.Children.Add("chop onions");
            prepare.Children.Add("grate cheese");
            prepare.Children.Add("measure milk");

            root.Children.Add("bake at 350 degrees F");

            SimpleTreeNode<string> cleanup = root.Children.Add("clean up");
            cleanup.Children.Add("do dishes");
            cleanup.Children.Add("wipe down counters");

            Console.WriteLine("-- cleanup subtree --\r\n\r\n");

            // display only the "clean up" subtree, passing in a SimpleTreeNode
            DisplayTree(cleanup, 0);

            Console.WriteLine("\r\n-- entire tree --\r\n\r\n");

            // display the whole subtree, passing in a SimpleTree
            DisplayTree(MakeDinnerTree, 0);



            Console.WriteLine("END");       
            
            
        }

        void DisplayTree(SimpleTreeNode<string> Subtree, int Level)
        {
            string indent = string.Empty.PadLeft(Level * 3);
            Console.WriteLine(indent + Subtree.Value + "\r\n");

            Level++;
            foreach (SimpleTreeNode<string> node in Subtree.Children)
            {
                DisplayTree(node, Level);
            }
        }

        void OutputTreeToWord(SimpleTreeNode<LabelText> Subtree, int Level, Word.Document oDoc)
        {
            //Test Comment
            Word.Paragraph oPara1;
            object oMissing = System.Reflection.Missing.Value;
            oPara1 = oDoc.Paragraphs.Add(ref oMissing);
            string indent = string.Empty.PadLeft(Level * 10);
            if (Subtree.Value.Text == "")
                oPara1.Range.Text = indent + Subtree.Value.Label;
            else
                oPara1.Range.Text = indent + Subtree.Value.Label + " - " + Subtree.Value.Text;
            if (Level == 0)
            {
                object styleHeading1 = "Heading 1";
                oPara1.Range.set_Style(ref styleHeading1);
            }
            else if(Level == 1)
            {
                object styleHeading2 = "Heading 2";
                oPara1.Range.set_Style(ref styleHeading2);
            }
            else if (Level == 2 && Subtree.Children.Count > 0)
            {
                object styleHeading3 = "Heading 3";
                oPara1.Range.set_Style(ref styleHeading3);
            }
                
            oPara1.Range.InsertParagraphAfter();
            
            Level++;

            foreach (SimpleTreeNode<LabelText> node in Subtree.Children)
            {
                OutputTreeToWord(node, Level,oDoc);
            }

         }
      
    }
}
